home *** CD-ROM | disk | FTP | other *** search
- From: Kay Roemer <roemer@informatik.uni-frankfurt.de>
- Posted-Date: Mon, 25 Oct 93 8:10:32 MEZ
- Received-Date: Mon, 25 Oct 93 08:10:32 +0100
- Message-Id: <9310250710.AA22270@hera.rbi.informatik.uni-frankfurt.de>
- Subject: fselect() ...
- To: mint@atari.archive.umich.edu
- Date: Mon, 25 Oct 93 8:10:32 MEZ
- Mailer: Elm [revision: 70.85]
-
- These diffs make Fselect() work for multiple
- processes selecting on the same file.
-
- The diffs are relative to 1.09 with my sleep()
- patches already applied (look at my previous
- message, the new Fselect() will only work with
- the patched sleep()).
-
- Cheers -- Kay.
-
- *** ../new/biosfs.c Fri Oct 22 20:58:26 1993
- --- biosfs.c Mon Sep 13 21:41:28 1993
- ***************
- *** 1236,1243 ****
- }
- if (tty) {
- /* avoid collisions with other processes */
- ! if (!tty->rsel)
- ! tty->rsel = p;
- }
- return 0;
- } else if (mode == O_WRONLY) {
- --- 1240,1248 ----
- }
- if (tty) {
- /* avoid collisions with other processes */
- ! if (tty->rsel)
- ! return 2; /* collsion */
- ! tty->rsel = p;
- }
- return 0;
- } else if (mode == O_WRONLY) {
- ***************
- *** 1246,1253 ****
- return 1;
- }
- if (tty) {
- ! if (!tty->wsel)
- ! tty->wsel = p;
- }
- return 0;
- }
- --- 1251,1259 ----
- return 1;
- }
- if (tty) {
- ! if (tty->wsel)
- ! return 2; /* collision */
- ! tty->wsel = p;
- }
- return 0;
- }
- ***************
- *** 1482,1489 ****
- if (mousetail - mousehead)
- return 1; /* input waiting already */
-
- ! if (!mousersel)
- ! mousersel = p;
- return 0;
- }
-
- --- 1488,1496 ----
- if (mousetail - mousehead)
- return 1; /* input waiting already */
-
- ! if (mousersel)
- ! return 2; /* collision */
- ! mousersel = p;
- return 0;
- }
-
- *** ../new/dosfile.c Fri Oct 22 20:58:26 1993
- --- dosfile.c Fri Oct 22 19:11:58 1993
- ***************
- *** 11,16 ****
- --- 11,19 ----
- static long do_dup P_((int,int));
- static void unselectme P_((PROC *));
-
- + /* wait condition for selecting processes which got collisions */
- + short select_coll;
- +
- /*
- * first, some utility routines
- */
- ***************
- *** 274,279 ****
- --- 277,284 ----
- if (f->dev) {
- (*f->dev->unselect)(f, (long)p, O_RDONLY);
- (*f->dev->unselect)(f, (long)p, O_WRONLY);
- + /* give other processes a chance to select on this file */
- + wake(SELECT_Q, (long)&select_coll);
- }
-
- f->links--;
- ***************
- *** 957,983 ****
- unsigned timeout;
- long *rfdp, *wfdp, *xfdp;
- {
- ! long rfd, wfd;
- long mask, bytes;
- int i, count;
- FILEPTR *f;
- PROC *p;
- ! TIMEOUT *t;
- short sr;
-
- if (xfdp)
- *xfdp = 0;
-
- if (rfdp) {
- ! rfd = *rfdp; *rfdp = 0;
- }
- else
- ! rfd = 0;
- if (wfdp) {
- ! wfd = *wfdp; *wfdp = 0;
- }
- else
- ! wfd = 0;
-
- TRACE(("Fselect(%u, %lx, %lx)", timeout, rfd, wfd));
- p = curproc; /* help the optimizer out */
- --- 962,988 ----
- unsigned timeout;
- long *rfdp, *wfdp, *xfdp;
- {
- ! long rfd, wfd, orfd, owfd;
- long mask, bytes;
- int i, count;
- FILEPTR *f;
- PROC *p;
- ! TIMEOUT *t = 0;
- short sr;
-
- if (xfdp)
- *xfdp = 0;
-
- if (rfdp) {
- ! orfd = rfd = *rfdp; *rfdp = 0;
- }
- else
- ! orfd = rfd = 0;
- if (wfdp) {
- ! owfd = wfd = *wfdp; *wfdp = 0;
- }
- else
- ! owfd = wfd = 0;
-
- TRACE(("Fselect(%u, %lx, %lx)", timeout, rfd, wfd));
- p = curproc; /* help the optimizer out */
- ***************
- *** 985,991 ****
- /* first, validate the masks */
- mask = 1L;
- for (i = 0; i < MAX_OPEN; i++) {
- ! if ( ((rfd & mask) || (wfd & mask)) && !(p->handle[i]) ) {
- DEBUG(("Fselect: invalid handle: %d", i));
- return EIHNDL;
- }
- --- 990,996 ----
- /* first, validate the masks */
- mask = 1L;
- for (i = 0; i < MAX_OPEN; i++) {
- ! if ( ((orfd & mask) || (owfd & mask)) && !(p->handle[i]) ) {
- DEBUG(("Fselect: invalid handle: %d", i));
- return EIHNDL;
- }
- ***************
- *** 1001,1043 ****
- * closed one of the handles.
- */
-
- - mask = 1L;
- count = 0;
- curproc->wait_cond = (long)wakeselect; /* flag */
-
- for (i = 0; i < MAX_OPEN; i++) {
- if (rfd & mask) {
- f = p->handle[i];
- ! if ((*f->dev->select)(f, (long)p, O_RDONLY)) {
- count++;
- *rfdp |= mask;
- }
- }
- if (wfd & mask) {
- f = p->handle[i];
- ! if ((*f->dev->select)(f, (long)p, O_WRONLY)) {
- count++;
- *wfdp |= mask;
- }
- }
- mask = mask << 1L;
- }
-
- if (count == 0) {
- ! /* OK, now let's set a timeout */
-
- ! if (timeout) {
- t = addtimeout((long)timeout, unselectme);
- - } else {
- - t = 0;
- }
-
- sr = spl7();
-
- /* curproc->wait_cond changes when data arrives or the timeout happens */
- while (curproc->wait_cond == (long)wakeselect) {
- TRACE(("sleeping in Fselect"));
- ! sleep(SELECT_Q, (long)wakeselect);
- }
- spl(sr);
-
- --- 1006,1075 ----
- * closed one of the handles.
- */
-
- count = 0;
- curproc->wait_cond = (long)wakeselect; /* flag */
-
- +
- + /* NOTE to the above note: since we can get here several times (in
- + * case of collisions) after we've gone to sleep, we probably cannot
- + * assume the filepointers are valid.
- + * I'm not really sure, because `post_sig' sets curproc->wait_cond
- + * to zero and then we cannot get here after we've gone to sleep.
- + */
- +
- + retry_after_collision:
- + mask = 1L;
- +
- for (i = 0; i < MAX_OPEN; i++) {
- if (rfd & mask) {
- f = p->handle[i];
- ! if (f) {
- ! switch ((*f->dev->select)(f, (long)p, O_RDONLY)) {
- ! case 1:
- count++;
- *rfdp |= mask;
- + case 0:
- + rfd &= ~mask;
- + }
- }
- }
- if (wfd & mask) {
- f = p->handle[i];
- ! if (f) {
- ! switch ((*f->dev->select)(f, (long)p, O_WRONLY)) {
- ! case 1:
- count++;
- *wfdp |= mask;
- + case 0:
- + wfd &= ~mask;
- + }
- }
- }
- mask = mask << 1L;
- }
-
- if (count == 0) {
- ! /* OK, now let's set a timeout, but only the first time we get here */
-
- ! if (!t && timeout) {
- t = addtimeout((long)timeout, unselectme);
- }
-
- sr = spl7();
-
- /* curproc->wait_cond changes when data arrives or the timeout happens */
- while (curproc->wait_cond == (long)wakeselect) {
- + long cond = (rfd || wfd) ? (long)&select_coll
- + : (long)wakeselect;
- +
- TRACE(("sleeping in Fselect"));
- ! if (sleep(SELECT_Q, cond))
- ! curproc->wait_cond = 0;
- ! }
- ! if (curproc->wait_cond == (long)&select_coll) {
- ! curproc->wait_cond = (long)wakeselect;
- ! spl(sr);
- ! goto retry_after_collision;
- }
- spl(sr);
-
- ***************
- *** 1047,1053 ****
- /* OK, let's see what data arrived (if any) */
- mask = 1L;
- for (i = 0; i < MAX_OPEN; i++) {
- ! if (rfd & mask) {
- f = p->handle[i];
- if (f) {
- bytes = 1L;
- --- 1079,1085 ----
- /* OK, let's see what data arrived (if any) */
- mask = 1L;
- for (i = 0; i < MAX_OPEN; i++) {
- ! if (orfd & mask) {
- f = p->handle[i];
- if (f) {
- bytes = 1L;
- ***************
- *** 1058,1064 ****
- }
- }
- }
- ! if (wfd & mask) {
- f = p->handle[i];
- if (f) {
- bytes = 1L;
- --- 1090,1096 ----
- }
- }
- }
- ! if (owfd & mask) {
- f = p->handle[i];
- if (f) {
- bytes = 1L;
- ***************
- *** 1071,1089 ****
- }
- mask = mask << 1L;
- }
- ! }
-
- /* at this point, we either have data or a time out */
- /* cancel all the selects */
- mask = 1L;
-
- for (i = 0; i < MAX_OPEN; i++) {
- ! if (rfd & mask) {
- f = p->handle[i];
- if (f)
- (*f->dev->unselect)(f, (long)p, O_RDONLY);
- }
- ! if (wfd & mask) {
- f = p->handle[i];
- if (f)
- (*f->dev->unselect)(f, (long)p, O_WRONLY);
- --- 1103,1127 ----
- }
- mask = mask << 1L;
- }
- ! } else if (t) {
-
- + /* in case data arrived after a collsion, there
- + * could be a timeout pending even if count > 0
- + */
- + canceltimeout(t);
- + }
- +
- /* at this point, we either have data or a time out */
- /* cancel all the selects */
- mask = 1L;
-
- for (i = 0; i < MAX_OPEN; i++) {
- ! if (orfd & mask) {
- f = p->handle[i];
- if (f)
- (*f->dev->unselect)(f, (long)p, O_RDONLY);
- }
- ! if (owfd & mask) {
- f = p->handle[i];
- if (f)
- (*f->dev->unselect)(f, (long)p, O_WRONLY);
- ***************
- *** 1091,1096 ****
- --- 1129,1138 ----
- mask = mask << 1L;
- }
-
- + /* wake other processes which got a collision */
- + if (orfd || owfd)
- + wake(SELECT_Q, (long)&select_coll);
- +
- TRACE(("Fselect: returning %d", count));
- return count;
- }
- *** ../new/pipefs.c Fri Oct 22 20:58:28 1993
- --- pipefs.c Mon Sep 13 21:44:34 1993
- ***************
- *** 1010,1018 ****
- return 1;
- }
-
- ! /* BUG: multiple selects fail, only the first one works */
- ! if (!p->rsel)
- ! p->rsel = proc;
- return 0;
- } else if (mode == O_WRONLY) {
- p = (f->flags & O_HEAD) ? this->inp : this->outp;
- --- 1010,1018 ----
- return 1;
- }
-
- ! if (p->rsel)
- ! return 2; /* collision */
- ! p->rsel = proc;
- return 0;
- } else if (mode == O_WRONLY) {
- p = (f->flags & O_HEAD) ? this->inp : this->outp;
- ***************
- *** 1024,1031 ****
- if (j >= PIPESIZ) j = 0;
- if (j != p->head || p->readers <= 0)
- return 1; /* data may be written */
- ! if (!p->wsel)
- ! p->wsel = proc;
- return 0;
- }
- return 0;
- --- 1024,1032 ----
- if (j >= PIPESIZ) j = 0;
- if (j != p->head || p->readers <= 0)
- return 1; /* data may be written */
- ! if (p->wsel)
- ! return 2; /* collsion */
- ! p->wsel = proc;
- return 0;
- }
- return 0;
- *** ../new/proc.c Fri Oct 22 20:59:28 1993
- --- proc.c Fri Oct 22 19:58:24 1993
- ***************
- *** 612,620 ****
- {
- PROC *p = (PROC *)param;
- short s;
- !
- s = spl7(); /* block interrupts */
- ! if(p->wait_cond == (long)wakeselect) {
- p->wait_cond = 0;
- }
- if (p->wait_q == SELECT_Q) {
- --- 612,622 ----
- {
- PROC *p = (PROC *)param;
- short s;
- ! extern short select_coll; /* in dosfile.c */
- !
- s = spl7(); /* block interrupts */
- ! if(p->wait_cond == (long)wakeselect ||
- ! p->wait_cond == (long)&select_coll) {
- p->wait_cond = 0;
- }
- if (p->wait_q == SELECT_Q) {
- *** ../new/signal.c Fri Oct 22 20:59:36 1993
- --- signal.c Fri Oct 22 20:58:10 1993
- ***************
- *** 85,93 ****
-
- /* otherwise, make sure the process is awake */
- if (p->wait_q && p->wait_q != READY_Q) {
- ! short sr = spl7();
- ! if (p->wait_q == SELECT_Q)
- ! p->wait_cond = 0;
- rm_q(p->wait_q, p);
- add_q(READY_Q, p);
- spl(sr);
- --- 85,91 ----
-
- /* otherwise, make sure the process is awake */
- if (p->wait_q && p->wait_q != READY_Q) {
- ! sr = spl7();
- rm_q(p->wait_q, p);
- add_q(READY_Q, p);
- spl(sr);
-
-